/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.manufacturers;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;


@WebService()
public class Manufacturer1 {

    private static final String PRODUCT_FILE = "Products1.xml";
    private static final String LOG_FILE = "Man1log.txt";


    private boolean produce(String prodName, int qty)
        {
            if(qty <= 100 && ("DVD Player".equalsIgnoreCase(prodName) || "video camera".equalsIgnoreCase(prodName) || "TV".equalsIgnoreCase(prodName)))
            {
                writeToLog("Producing " + qty + " of " + prodName);
                return true;
            }
            else
            {
                return false;
            }
        }

    /**
     * Web service operation
     */
    @WebMethod(operationName = "processPurchaseOrder")
    public Boolean processPurchaseOrder(@WebParam(name = "aPO")
    PurchaseOrder aPO) {

        DocumentBuilderFactory docBuilderFactory = null;
        DocumentBuilder docBuilder = null;
        Document doc = null;

        try
        {

          docBuilderFactory = DocumentBuilderFactory.newInstance();
          docBuilder = docBuilderFactory.newDocumentBuilder();
          doc = docBuilder.parse (new File(Manufacturer1.class.getResource(PRODUCT_FILE).toURI()));


        } catch (URISyntaxException ex) {
            Logger.getLogger(Manufacturer1.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SAXException ex) {
            Logger.getLogger(Manufacturer1.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Manufacturer1.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ParserConfigurationException ex) {
            Logger.getLogger(Manufacturer1.class.getName()).log(Level.SEVERE, null, ex);
        }


        NodeList allProducts = doc.getElementsByTagName("*");
        doc.getDocumentElement().normalize();

        int priceFromXML = -1;

        for (int i=0; i < allProducts.getLength(); i++)
        {
            Node node = allProducts.item(i);
            if (node.getNodeType() == Node.ELEMENT_NODE)
            {
                Element element = (Element) node;

                if(element.getAttribute("product-type").equalsIgnoreCase(aPO.getProduct().getProductType()))
                {
                    priceFromXML = Integer.parseInt(element.getAttribute("unit-price"));
                    //System.out.println(element.getTagName() + " " + element.getAttribute("unit-price") + " And my price is " + priceFromXML);
                }
            }
        }


            //Link to XML file to check that files unit price.
            if (aPO.getUnitPrice() >= priceFromXML)
            {
                //System.out.println("\nINSIDE THE PRICE check " + priceFromXML);

                boolean check1 = false, check2 = false;
                int q1 = aPO.getQuantity();
                int q2 = q1 / 100;


                while(q2 > 0)
                {
                    check1 = produce(aPO.getProduct().getProductType(), 100);
                    q2--;
                }


                //checks if theres less then a quantity of 100, the it produces just 1.
                int q3 = q1 % 100;

                if (q3 > 0)
                {
                    check2 = produce(aPO.getProduct().getProductType(), q3);
                }


                // if both checks come out true then write to the XML file.
                if (check1 || check2)
                {

                  //creating the root element purchase-order
                  doc = docBuilder.newDocument();
                  Element rootElement = doc.createElement("purchase-order");
                  doc.appendChild(rootElement);


                  Attr attr1 = doc.createAttribute("number");
              	  attr1.setValue(aPO.getOrderNum());
                  rootElement.setAttributeNode(attr1);

                  Attr attr2 = doc.createAttribute("customerref");
              	  attr2.setValue(aPO.getCustomerRef());
                 rootElement.setAttributeNode(attr2);

                  Attr attr3 = doc.createAttribute("quantity");
              	  attr3.setValue(String.valueOf(aPO.getQuantity()));
                  rootElement.setAttributeNode(attr3);

                  Attr attr4 = doc.createAttribute("paid");
              	  attr4.setValue("false");
            	  rootElement.setAttributeNode(attr4);


                  //creating the product element inside purchase-order
                  Element productElement = doc.createElement("product");
                  rootElement.appendChild(productElement);

                  Attr attr5 = doc.createAttribute("manufacturer-name");
                  attr5.setValue(aPO.getProduct().getManufacturerName());
                  productElement.setAttributeNode(attr5);

                  Attr attr6 = doc.createAttribute("product-type");
                  attr6.setValue(aPO.getProduct().getProductType());
                  productElement.setAttributeNode(attr6);

                  Attr attr7 = doc.createAttribute("unit-price");
                  attr7.setValue(String.valueOf(aPO.getProduct().getUnitPrice()));
                  productElement.setAttributeNode(attr7);


                  //Writing to the file

                  try
                  {

                    TransformerFactory transformerFactory = TransformerFactory.newInstance();
                    Transformer transformer = transformerFactory.newTransformer();

                    DOMSource source = new DOMSource(doc);
                    String receivedOrder = "Orders1/" + aPO.getOrderNum() + ".xml";

                    //StreamResult result = new StreamResult(new File("/Users/DJDocStrange/NetBeansProjects/WHandMF1/web/WEB-INF/files/"+ aPO.getOrderNum() + ".xml"));
                    String directory = Manufacturer1.class.getResource(PRODUCT_FILE).toURI().toString();
                    String directory2 = directory.substring(5, directory.length()-13);
                    String directory3 = directory2 + receivedOrder;
                    //System.out.println(directory3);
                    StreamResult result = new StreamResult(new File(directory3));


                    transformer.transform(source, result);

                    //DEBUG
                    System.out.println("File saved!");

                    } catch (URISyntaxException ex) {
                        Logger.getLogger(Manufacturer1.class.getName()).log(Level.SEVERE, null, ex);
                    } catch (TransformerException ex) {
                        Logger.getLogger(Manufacturer1.class.getName()).log(Level.SEVERE, null, ex);
                    }



                return true;

                }
                else
                {
                    return false;

                }
            }
            else
            {
                return false;
            }


    }

    /**
     * Web service operation
     */
    @WebMethod(operationName = "getProductInfo")
    public Product getProductInfo(@WebParam(name = "aProdName")
    String aProdName) {

        
        if("DVD Player".equalsIgnoreCase(aProdName) || "video camera".equalsIgnoreCase(aProdName) || "TV".equalsIgnoreCase(aProdName))
        {


        DocumentBuilderFactory docBuilderFactory = null;
        DocumentBuilder docBuilder = null;
        Document doc = null;

            try
            {

              docBuilderFactory = DocumentBuilderFactory.newInstance();
              docBuilder = docBuilderFactory.newDocumentBuilder();
              
              doc = docBuilder.parse (new File(Manufacturer1.class.getResource(PRODUCT_FILE).toURI()));


            } catch (URISyntaxException ex) {
                Logger.getLogger(Manufacturer1.class.getName()).log(Level.SEVERE, null, ex);
            } catch (SAXException ex) {
                Logger.getLogger(Manufacturer1.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
                Logger.getLogger(Manufacturer1.class.getName()).log(Level.SEVERE, null, ex);
            } catch (ParserConfigurationException ex) {
                Logger.getLogger(Manufacturer1.class.getName()).log(Level.SEVERE, null, ex);
            }


        NodeList allProducts = doc.getElementsByTagName("*");
        doc.getDocumentElement().normalize();

        Product p;

        for (int i=0; i < allProducts.getLength(); i++)
        {
            Node node = allProducts.item(i);
            if (node.getNodeType() == Node.ELEMENT_NODE)
            {
                Element element = (Element) node;

                if(element.getAttribute("product-type").equalsIgnoreCase(aProdName) )
                {
                    p = new Product(element.getAttribute("manufacturer-name"), element.getAttribute("product-type"), Float.parseFloat(element.getAttribute("unit-price")));
                    return p;
                }
            }
        }


       }

        return null;

    }

    /**
     * Web service operation
     */
    @WebMethod(operationName = "receivePayment")
    public Boolean receivePayment(@WebParam(name = "orderNum")
    String orderNum, @WebParam(name = "totalPrice")
    Float totalPrice) {

        DocumentBuilderFactory docBuilderFactory = null;
        DocumentBuilder docBuilder = null;
        Document doc = null;
        String receivedOrder = orderNum + ".xml";

        try
        {

          docBuilderFactory = DocumentBuilderFactory.newInstance();
          docBuilder = docBuilderFactory.newDocumentBuilder();
          doc = docBuilder.parse (new File(Manufacturer1.class.getResource(receivedOrder).toURI()));



          if(doc == null){
              return false;}

        } catch (URISyntaxException ex) {
            Logger.getLogger(Manufacturer1.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SAXException ex) {
            Logger.getLogger(Manufacturer1.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Manufacturer1.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ParserConfigurationException ex) {
            Logger.getLogger(Manufacturer1.class.getName()).log(Level.SEVERE, null, ex);
        }


        NodeList order = doc.getElementsByTagName("*");
        doc.getDocumentElement().normalize();



        int qty = -1;
        float unitp = -1;
        Attr paid = null;

        for (int i=0; i < order.getLength(); i++)
        {
            Node node = order.item(i);

            if (node.getNodeType() == Node.ELEMENT_NODE)
            {
                Element element = (Element) node;

                if(element.getNodeName().equalsIgnoreCase("purchase-order"))
                    {
                        paid = element.getAttributeNode("paid");
                        qty = Integer.parseInt(element.getAttribute("quantity"));
                    }

                if(element.getNodeName().equalsIgnoreCase("product"))
                    {
                        unitp = Float.parseFloat(element.getAttribute("unit-price"));
                    }
            }
        }


        if(totalPrice == (qty * unitp))
        {

            //mark order as true (paid) instead of default false
            paid.setValue("true");


                 //Writing to the file
                  try
                  {

                    TransformerFactory transformerFactory = TransformerFactory.newInstance();
                    Transformer transformer = transformerFactory.newTransformer();

                    DOMSource source = new DOMSource(doc);
                    //StreamResult result = new StreamResult(new File("/Users/DJDocStrange/NetBeansProjects/WHandMF1/web/WEB-INF/files/"+ orderNum + ".xml"));
                    //StreamResult result = new StreamResult(new File(manufacturerWS.class.getResource(receivedOrder).toURI()));

                    String directory = Manufacturer1.class.getResource(PRODUCT_FILE).toURI().toString();
                    String directory2 = directory.substring(5, directory.length()-12);
                    String directory3 = directory2 + receivedOrder;
                    //System.out.println(directory3);
                    StreamResult result = new StreamResult(new File(directory3));



                    transformer.transform(source, result);

                    //DEBUG
                    System.out.println("File saved!");

            } catch (URISyntaxException ex) {
                Logger.getLogger(Manufacturer1.class.getName()).log(Level.SEVERE, null, ex);
            } catch (TransformerException ex) {
                Logger.getLogger(Manufacturer1.class.getName()).log(Level.SEVERE, null, ex);
            }

            return true;
        }
        else
        return false;
    }

    /**
     * Web service operation
     */
    @WebMethod(operationName = "getOrders")
    public java.util.ArrayList<PurchaseOrder> getOrders(@WebParam(name = "asynch")
    boolean asynch) 
    {
        ArrayList<PurchaseOrder> pOList = new ArrayList<PurchaseOrder>();

        // getting a list of the Order Files
        File[] orderFileList = null;
        String folder = "";

        try
        {
            folder = Manufacturer1.class.getResource(PRODUCT_FILE).toURI().toString();
            folder = folder.substring(5, folder.length()-13) + "Orders1";

            System.out.println(folder);

        }
        catch(Exception e)
        {
            e.printStackTrace();
        }


        File f = new File(folder);
        orderFileList = f.listFiles();

        System.out.println("\n\n==================\nFILES:");
        for(int i=0; i< orderFileList.length; i++)
        {
            System.out.println( orderFileList[i].getAbsolutePath() );
        }
        System.out.println("==================\n\n");



        // read each file and create a purchaseOrder for each one
        for(int k=0; k< orderFileList.length; k++)
        {
           DocumentBuilderFactory docBuilderFactory = null;
            DocumentBuilder docBuilder = null;
            Document doc = null;

            try
            {

              docBuilderFactory = DocumentBuilderFactory.newInstance();
              docBuilder = docBuilderFactory.newDocumentBuilder();
              doc = docBuilder.parse ( orderFileList[k] );

            } catch (SAXException ex) {
                Logger.getLogger(Manufacturer1.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
                Logger.getLogger(Manufacturer1.class.getName()).log(Level.SEVERE, null, ex);
            } catch (ParserConfigurationException ex) {
                Logger.getLogger(Manufacturer1.class.getName()).log(Level.SEVERE, null, ex);
            }


            PurchaseOrder pO = new PurchaseOrder();

            Element filePO = (Element) doc.getElementsByTagName("purchase-order").item(0);
            Element fileProd = (Element) doc.getElementsByTagName("product").item(0);

            pO.setCustomerRef(filePO.getAttribute("customerref"));
            pO.setOrderNum( filePO.getAttribute("number") );
            pO.setPaid(false);
            pO.setQuantity( Integer.parseInt( filePO.getAttribute("quantity") ));
            pO.setUnitPrice( Float.parseFloat( fileProd.getAttribute("unit-price") ) );

            pO.setProduct(getProductInfo( fileProd.getAttribute("product-type")) );

            pOList.add(pO);

        }


        return pOList;

    }

    private boolean writeToLog(String input)
    {

        PrintWriter outputStream = null;
        String folder = "";




        try {

            folder = Manufacturer1.class.getResource(PRODUCT_FILE).toURI().toString();
            folder = folder.substring(5, folder.length()-13);
            outputStream = new PrintWriter(new FileOutputStream(folder + LOG_FILE, true));


        } catch (URISyntaxException ex) {
            Logger.getLogger(Manufacturer1.class.getName()).log(Level.SEVERE, null, ex);
        } catch (FileNotFoundException ex) {
           // Logger.getLogger(Manufacturer1.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println("Error writing to the log file for Man 1");
        }

        System.out.println("Writing to log file for Manufacturer 1...");

        outputStream.println(input);
        outputStream.close();

        System.out.println("Finished writing...");

        return true;


    }

}
